import json
import argparse
from urllib.parse import urlparse, parse_qs
from datetime import datetime

def parse_har_file(har_file_path):
    """解析HAR文件并提取接口信息"""
    try:
        with open(har_file_path, 'r', encoding='utf-8') as f:
            har_data = json.load(f)
    except Exception as e:
        print(f"Error loading HAR file: {e}")
        return []
    
    api_endpoints = {}
    
    # 遍历HAR文件中的所有请求条目
    for entry in har_data.get('log', {}).get('entries', []):
        request = entry.get('request', {})
        response = entry.get('response', {})
        
        # 提取URL和路径
        url = request.get('url', '')
        parsed_url = urlparse(url)
        path = parsed_url.path
        method = request.get('method', 'GET')
        
        # 生成唯一的端点标识 (method + path)
        endpoint_key = f"{method} {path}"
        
        # 如果该端点尚未记录，则初始化
        if endpoint_key not in api_endpoints:
            api_endpoints[endpoint_key] = {
                'method': method,
                'path': path,
                'description': '',
                'queries': {},
                'headers': {},
                'request_body': None,
                'request_body_type': '',
                'responses': []
            }
        
        # 提取查询参数
        query_params = parse_qs(parsed_url.query)
        for param, values in query_params.items():
            if param not in api_endpoints[endpoint_key]['queries']:
                api_endpoints[endpoint_key]['queries'][param] = {
                    'description': '',
                    'required': False,
                    'example': values[0] if values else ''
                }
        
        # 提取请求头
        for header in request.get('headers', []):
            name = header.get('name', '').lower()
            value = header.get('value', '')
            if name and name not in ['cookie', 'host']:  # 排除常见的非关键头
                api_endpoints[endpoint_key]['headers'][name] = value
        
        # 提取请求体
        post_data = request.get('postData', {})
        if post_data:
            mimeType = post_data.get('mimeType', '')
            text = post_data.get('text', '')
            
            if mimeType == 'application/json' and text:
                try:
                    api_endpoints[endpoint_key]['request_body'] = json.loads(text)
                    api_endpoints[endpoint_key]['request_body_type'] = 'json'
                except json.JSONDecodeError:
                    api_endpoints[endpoint_key]['request_body'] = text
                    api_endpoints[endpoint_key]['request_body_type'] = 'text'
            else:
                api_endpoints[endpoint_key]['request_body'] = text
                api_endpoints[endpoint_key]['request_body_type'] = mimeType
        
        # 提取响应
        status = response.get('status', 0)
        content = response.get('content', {})
        response_text = content.get('text', '')
        
        response_data = {
            'status': status,
            'headers': {h.get('name', '').lower(): h.get('value', '') for h in response.get('headers', [])},
            'content_type': content.get('mimeType', ''),
            'body': None
        }
        
        # 尝试解析JSON响应
        if response_text and 'application/json' in response_data['content_type']:
            try:
                response_data['body'] = json.loads(response_text)
            except json.JSONDecodeError:
                response_data['body'] = response_text[:500] + '...' if len(response_text) > 500 else response_text
        else:
            response_data['body'] = response_text[:500] + '...' if len(response_text) > 500 else response_text
        
        api_endpoints[endpoint_key]['responses'].append(response_data)
    
    return list(api_endpoints.values())

def generate_markdown_docs(api_endpoints, output_file=None):
    """生成Markdown格式的接口文档"""
    markdown = "# API接口文档\n"
    markdown += f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
    markdown += f"总接口数: {len(api_endpoints)}\n\n"
    
    # 按路径排序
    api_endpoints.sort(key=lambda x: x['path'])
    
    for endpoint in api_endpoints:
        method = endpoint['method']
        path = endpoint['path']
        
        # 端点标题
        markdown += f"## {method} {path}\n\n"
        
        # 描述（如果有）
        if endpoint['description']:
            markdown += f"{endpoint['description']}\n\n"
        
        # 请求URL示例
        markdown += "### 请求URL\n"
        markdown += f"```\n{method} {path}\n```\n\n"
        
        # 查询参数
        if endpoint['queries']:
            markdown += "### 查询参数\n"
            markdown += "| 参数名 | 类型 | 是否必选 | 描述 | 示例 |\n"
            markdown += "|--------|------|----------|------|------|\n"
            for param, info in endpoint['queries'].items():
                markdown += f"| {param} | string | {'是' if info['required'] else '否'} | {info['description']} | {info['example']} |\n"
            markdown += "\n"
        
        # 请求头
        if endpoint['headers']:
            markdown += "### 请求头\n"
            markdown += "| 头信息 | 值 |\n"
            markdown += "|--------|-----|\n"
            for name, value in endpoint['headers'].items():
                markdown += f"| {name} | {value} |\n"
            markdown += "\n"
        
        # 请求体
        if endpoint['request_body'] is not None:
            markdown += "### 请求体\n"
            markdown += f"**类型**: {endpoint['request_body_type']}\n\n"
            
            if endpoint['request_body_type'] == 'json':
                # 美化JSON格式
                try:
                    json_body = json.dumps(endpoint['request_body'], indent=2, ensure_ascii=False)
                    markdown += "```json\n"
                    markdown += f"{json_body}\n"
                    markdown += "```\n\n"
                except:
                    markdown += f"```\n{str(endpoint['request_body'])}\n```\n\n"
            else:
                markdown += f"```\n{str(endpoint['request_body'])}\n```\n\n"
        
        # 响应
        if endpoint['responses']:
            markdown += "### 响应\n"
            
            for response in endpoint['responses']:
                status = response['status']
                content_type = response['content_type']
                
                markdown += f"#### HTTP状态码: {status}\n"
                markdown += f"**Content-Type**: {content_type}\n\n"
                
                if response['body'] is not None:
                    if isinstance(response['body'], dict) or isinstance(response['body'], list):
                        # 美化JSON格式
                        try:
                            json_body = json.dumps(response['body'], indent=2, ensure_ascii=False)
                            markdown += "```json\n"
                            markdown += f"{json_body}\n"
                            markdown += "```\n\n"
                        except:
                            markdown += f"```\n{str(response['body'])}\n```\n\n"
                    else:
                        # 文本响应
                        body_text = str(response['body'])
                        if len(body_text) > 1000:
                            body_text = body_text[:1000] + "..."
                        markdown += "```\n"
                        markdown += f"{body_text}\n"
                        markdown += "```\n\n"
                else:
                    markdown += "```\n无响应内容\n```\n\n"
        
        # 分隔线
        markdown += "---\n\n"
    
    # 保存到文件或打印到控制台
    if output_file:
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(markdown)
        print(f"文档已保存到: {output_file}")
    else:
        print(markdown)
    
    return markdown

def main():
    parser = argparse.ArgumentParser(description='从HAR文件生成API接口文档')
    parser.add_argument('har_file', help='HAR文件路径')
    parser.add_argument('-o', '--output', help='输出Markdown文件路径')
    args = parser.parse_args()
    
    api_endpoints = parse_har_file(args.har_file)
    if api_endpoints:
        generate_markdown_docs(api_endpoints, args.output)
    else:
        print("未能从HAR文件中提取到有效接口信息")

if __name__ == "__main__":
    main()    